package org.example.mallchat.common.service;

import org.example.mallchat.exception.BusinessException;
import org.example.mallchat.exception.ErrorCode;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
 * @author: zzh
 * @date: 2024/12/23 22:10:37
 * @version: 1.0
 */
@Service
public class RedissonServiceUtils {

    @Resource
    private RedissonClient redissonClient;

    /**
     * 执行带有锁的操作，如果获取锁失败，则抛出异常
     * @param key       锁的key
     * @param waitTime  等待时间
     * @param unit 时间单位
     * @param supplier 业务逻辑
     * @return
     * @param <T>
     * @throws InterruptedException
     */
    public <T> T executeWithLock(String key, int waitTime, TimeUnit unit, Supplier<T> supplier) throws InterruptedException {
        RLock lock = redissonClient.getLock(key);
        boolean success = lock.tryLock(waitTime, unit);
        if (!success){
           throw new BusinessException(ErrorCode.FREQUENT_REQUEST);
        }
        try {
            return supplier.get();
        }finally {
            lock.unlock();
        }
    }

    public <T> T executeWithLock(String key, Supplier<T> supplier) throws InterruptedException {
        return executeWithLock(key,-1,TimeUnit.MICROSECONDS,supplier);
    }

}
